package wiiusej.apptest.activityTasks;

import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.PropertyConfigurator;

import wiiusej.Wiimote;


public class EnergyTransmisionTask implements Runnable{
	
	private final Wiimote myWiimote;
	
	//Logger
	static Logger fileLogger;
	private static final String fileURL = "src/test/java/wiiusej/resources/logs/tasks/Energy_Wiimote_";
	
	private AtomicInteger energyCharged;
	
	//Speaker Parameters
	private static final int FIRST_LEVEL_FREQ = 1250;
	private static final int SECOND_LEVEL_FREQ = 1000;
	private static final int THIRD_LEVEL_FREQ = 500;
	private static final int FOURTH_LEVEL_FREQ = 250;
	
	private static final int FIFTH_LEVEL_FREQ = 350;
	private static final int SIXTH_LEVEL_FREQ = 200;
	
	//FREQ LEVELS
	private static final int FIRST_LEVEL = 1;
	private static final int SECOND_LEVEL = 7;
	private static final int THIRD_LEVEL = 14;
	private static final int FOURTH_LEVEL = 21;
	private static final int CHARGED = 30;
	
	//Energy Constants
	private static final int SPELL_CAST = 0; //triggered by WiimoteListener when eventually A button is pressed
	private static final int ENERGY_UNIT = 1;
	
	//to Game constants
	private static final int STOP = 0;
	private static final int RUN = 1;
	
	
	private static final int FIFTH_LEVEL = 80;
	private static final int SIXTH_LEVEL = 100;
	
	private int currentFreqLevel = 0;
	
	
	private BlockingQueue<Integer> fromGame = new LinkedBlockingDeque<Integer>();
	private BlockingQueue<Spell> toComClient = new LinkedBlockingDeque<Spell>();
	
	private BlockingQueue<Integer> toRumbleQ = new LinkedBlockingQueue<Integer>();
	private BlockingQueue<Integer> toLEDQ = new LinkedBlockingQueue<Integer>();
	private ConcurrentLinkedQueue<Integer> toGameQ;
	
	public EnergyTransmisionTask(Wiimote wiimote, BlockingQueue<Integer> fromGame, 
			BlockingQueue<Spell> toComClient, BlockingQueue<Integer> toRumbleQ2, BlockingQueue<Integer> toLEDQ,
			ConcurrentLinkedQueue<Integer> fromEnergyToGameQ){
		
		this.myWiimote = wiimote;
		
		this.fromGame = fromGame;
		
		this.toRumbleQ = toRumbleQ2;
		this.toLEDQ = toLEDQ;
		this.toComClient = toComClient;
		
		this.toGameQ =  fromEnergyToGameQ;
		
		this.energyCharged = new AtomicInteger(0);		
		
		PropertyConfigurator.configure("log4j.properties");
		fileLogger = Logger.getLogger("energyCharged");
		
		PatternLayout pattern = 
			new PatternLayout("%r [%t] %-5p %c %x - %m%n");		
		
		try {			
			//Creating a file for every connected wiimote
			FileAppender fileappend=new FileAppender(pattern, fileURL + wiimote.getId() + ".log");
			fileLogger.addAppender(fileappend);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}	
	
	
	@Override
	public void run() {
		
		while(true){
		
			try {				
				receiveCommand(fromGame.take());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}				
			
			//chargeEnergy(energyCharged.get());			
			
			
			switch(energyCharged.get()){
				//volume 8		
							
				case FIRST_LEVEL:
					//currentFreqLevel = FIRST_LEVEL_FREQ;
					//toRumbleQ.add(currentFreqLevel);					
					//myWiimote.setLeds(true, false, false, false);
					
					toLEDQ.add(1);
					
					fileLogger.debug("FIRST LEVEL: " + FIRST_LEVEL);
					break;					
					
				case SECOND_LEVEL:
					//currentFreqLevel = SECOND_LEVEL_FREQ;
				
					//toRumbleQ.add(currentFreqLevel);
					myWiimote.setLeds(true, false, false, false);
					
					toLEDQ.add(2);
					fileLogger.debug("SECOND LEVEL: " + SECOND_LEVEL);
					
					break;
					
				case THIRD_LEVEL:
					//currentFreqLevel = THIRD_LEVEL_FREQ;
					//toRumbleQ.add(currentFreqLevel);					
					//myWiimote.setLeds(true, true, true, false);
					
					toLEDQ.add(3);
					fileLogger.debug("THIRD LEVEL: " + THIRD_LEVEL);
					break;
					
				case FOURTH_LEVEL:
					//currentFreqLevel = FOURTH_LEVEL_FREQ;
					//toRumbleQ.add(currentFreqLevel);					
					//myWiimote.setLeds(true, true, true, true);
					toLEDQ.add(4);
					fileLogger.debug("FOURTH LEVEL: " + FOURTH_LEVEL);
					break;			
					
				case CHARGED:
					toLEDQ.add(5);
					fileLogger.debug("CHARGED: " + CHARGED);
				
				default:
					//toRumbleQ.add(currentFreqLevel);
					break;
					
			}
			
			
			if(energyCharged.get() >= CHARGED){
				
				toGameQ.offer(STOP);
				//setBlinkyLigth();				
				
				try {					
					//wait until button A is pressed by the user
					do{						
					}while(!receiveCommand(fromGame.take()));					
					
					toLEDQ.add(0);
					
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				
			}
			//toGameQ.offer(RUN);
			
			
			
		}
		
		
		
		
	}	
	
	private boolean receiveCommand(Integer i) {
		
		boolean casted = false;
		
		switch(i){		
		
		
		
		case SPELL_CAST:						
			//toComClient.put(energyCharged*2);
			//reset the energy level
			
			//CLIENT NOTIFICATION 
			
			if(energyCharged.get() < 30){
				System.out.println("NEED MORE ENERGY");
				casted = false;
			}else{
				
				System.out.println("Sending the Spell to the CLIENT");
				Spell castedSpell = new Spell(myWiimote, energyCharged.get());
				toComClient.add(castedSpell);
				
				energyCharged.set(0);			
				System.out.println("RESET ENERGY - SPELL CASTED -  ENERGY: " + energyCharged);
							
				myWiimote.setLeds(true, false, false, false);
				fileLogger.info("");
				
				//notice game that could run again
				System.out.println("Sending COmmand to GAME: " + RUN);
				toGameQ.offer(RUN);
				
				casted = true;
				
			}
			
			break;
						
			
		case ENERGY_UNIT:
			//System.out.println("Received from Queue: " + i);
			energyCharged.incrementAndGet();		
			System.out.println("EnergyCharged: " + energyCharged);		
			break;
		}
		
		//System.out.println("CASTED: " + casted );
		return casted;
		
		
	}
	
	/*
	private void chargeEnergy(int i) {
		
		
	}*/


	private void setBlinkyLigth(){
		/*
		try {			
			for(int i = 0; i<7; i++){
				
				myWiimote.setLeds(true, true, true, true);
				Thread.sleep(500);
				myWiimote.setLeds(false, false, false, false);
				Thread.sleep(500);
			}			
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
	}
	
	

}
